package com.fast.fast.upms.biz.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fast.fast.common.base.exception.BizException;
import com.fast.fast.common.base.page.PageResult;
import com.fast.fast.upms.api.entity.SysUser;
import com.fast.fast.upms.api.entity.SysUserPost;
import com.fast.fast.upms.api.entity.SysUserRole;
import com.fast.fast.upms.biz.base.util.ClearAuthUtils;
import com.fast.fast.upms.biz.mapper.SysUserMapper;
import com.fast.fast.upms.biz.service.SysUserPostService;
import com.fast.fast.upms.biz.service.SysUserRoleService;
import com.fast.fast.upms.biz.service.SysUserService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author lyf
 * @description 针对表【sys_user(系统用户表)】的数据库操作Service实现
 * @createDate 2022/01/01 00:00 周六
 */
@RequiredArgsConstructor
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser>
        implements SysUserService {

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private SysUserPostService sysUserPostService;

    @Autowired
    private SysUserRoleService sysUserRoleService;

    @Autowired
    private ClearAuthUtils clearAuthUtils;

    @Override
    public Long mySaveOrUpdate(SysUser sysUser) {
        // 新增
        if (ObjectUtil.isEmpty(sysUser.getId())) {
            // 校验用户名是否重复,即使是不同租户,用户名也不能一样
            SysUser oldSysUser = sysUserMapper.getByUsername(sysUser);
            if (oldSysUser != null) {
                throw new BizException("用户名重复");
            }
            if (ObjUtil.isNotEmpty(sysUser.getPassword())) {
                // md5加密
                String password = SecureUtil.md5(sysUser.getPassword());
                sysUser.setPassword(password);
            }
        } else { //更新
            String newPassword = sysUser.getPassword();
            if (ObjUtil.isNotEmpty(newPassword)) {
                String oldPassword = getById(sysUser.getId()).getPassword();
                if (!newPassword.equals(oldPassword)) {
                    // md5加密
                    newPassword = SecureUtil.md5(newPassword);
                    sysUser.setPassword(newPassword);
                }
            }
        }
        super.saveOrUpdate(sysUser);
        // 清除指定用户的登录信息
        clearAuthUtils.clearSpecifiedUserLoginInfo(Collections.singletonList(sysUser.getId()));
        return sysUser.getId();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean delete(List<Long> ids) {
        removeBatchByIds(ids);
        if (ObjUtil.isNotEmpty(ids)) {
            // 删除系统用户与岗位关联表数据
            List<Long> sysUserPostIds = sysUserPostService.list(Wrappers.lambdaQuery(SysUserPost.class)
                    .in(SysUserPost::getUserId, ids)
            ).stream().map(SysUserPost::getId).collect(Collectors.toList());
            sysUserPostService.removeBatchByIds(sysUserPostIds);

            // 删除系统用户角色关联表数据
            List<Long> sysUserRoleIds = sysUserRoleService.list(Wrappers.lambdaQuery(SysUserRole.class)
                    .in(SysUserRole::getUserId, ids)
            ).stream().map(SysUserRole::getId).collect(Collectors.toList());
            sysUserRoleService.removeBatchByIds(sysUserRoleIds);

            // 清除指定用户的登录信息
            clearAuthUtils.clearSpecifiedUserLoginInfo(ids);

            // 如果删除的包括当前登录用户，退出登录
            Long loginId = Long.valueOf((String) StpUtil.getLoginId());
            if (ids.contains(loginId)) {
                StpUtil.logout();
            }
        }
        return true;
    }

    @Override
    public SysUser getByUsernameAndPwd(SysUser sysUser) {
        // md5加密
        sysUser.setPassword(SecureUtil.md5(sysUser.getPassword()));
        return sysUserMapper.getByUsernameAndPwd(sysUser);
    }

    @Override
    public boolean setStatus(SysUser sysUser) {
        LambdaUpdateWrapper<SysUser> wrapper = Wrappers.lambdaUpdate(SysUser.class)
                .set(ObjectUtil.isNotEmpty(sysUser.getStatus()), SysUser::getStatus, sysUser.getStatus())
                .eq(ObjectUtil.isNotEmpty(sysUser.getId()), SysUser::getId, sysUser.getId());
        update(wrapper);
        return true;
    }

    @Override
    public boolean updatePassword(SysUser sysUser) {
        // md5加密
        String password = SecureUtil.md5(sysUser.getPassword());
        update(Wrappers.lambdaUpdate(SysUser.class)
                .set(ObjectUtil.isNotEmpty(password), SysUser::getPassword, password)
                .eq(SysUser::getId, StpUtil.getLoginId())
        );
        // 清除登录用户的登录信息
        clearAuthUtils.clearLoginUserLoginInfo();
        return true;
    }

    @Override
    public PageResult<SysUser> myPage(SysUser po) {
        Page<SysUser> page = new Page<>(po.getCurrent() == null ? 1 : po.getCurrent(), po.getSize() == null ? 10 : po.getSize());
        page.setOptimizeCountSql(false);
        page = getBaseMapper().myPage(page, po);
        page.getRecords().forEach(o -> {
            List<String> roleNames = StrUtil.split(o.getRoleNamesStr(), ",");
            List<String> roleIds = StrUtil.split(o.getRoleIdsStr(), ",");
            o.setRoleNames(roleNames);
            o.setRoleIds(roleIds);
        });
        return PageResult.of(page);
    }

}




